#include "serial.hpp"
#include <iostream>
#include <boost/bind/bind.hpp>

SerialPort::SerialPort() 
    : serial_port_(io_service_), 
      is_running_(false),
      receive_buffer_(1024)  // 1KB接收缓冲区
{
}

SerialPort::~SerialPort() {
    close();
}

bool SerialPort::open(const std::string& port_name, unsigned int baud_rate) {
    std::lock_guard<std::mutex> lock(mutex_);
    
    // 如果已打开则先关闭
    if (serial_port_.is_open()) {
        close();
    }
//std::cout<< "run thread async receive" << std::endl;
    try {
        // 打开串口
        serial_port_.open(port_name);
      //  std::cout<< "open=" << port_name <<" baud=" << baud_rate << std::endl;
        // 配置串口参数（只需要设置波特率，其他使用默认值）

        serial_port_.set_option(serial_port::baud_rate(baud_rate));
        serial_port_.set_option(serial_port::flow_control(serial_port::flow_control::none));
        serial_port_.set_option(serial_port::parity(serial_port::parity::none));
        serial_port_.set_option(serial_port::stop_bits(serial_port::stop_bits::one));
        serial_port_.set_option(serial_port::character_size(8));


        // 启动接收线程
        is_running_ = true;
        receive_thread_ = std::thread(&SerialPort::receive_thread, this);
        last_error_.clear();
        return true;
    } 
    catch (const boost::system::system_error& e) {
        last_error_ = e.what();
        std::cerr << "打开串口失败: " << last_error_ << std::endl;
        is_running_ = false;
        return false;
    }
}

void SerialPort::close() {
    std::lock_guard<std::mutex> lock(mutex_);
    
    if (!serial_port_.is_open()) {
        return;
    }

    // 停止接收线程
    is_running_ = false;
    if (receive_thread_.joinable()) {
        io_service_.stop();
        receive_thread_.join();
        io_service_.reset();
    }

    // 关闭串口
    try {
        if (serial_port_.is_open()) {
            serial_port_.close();
        }
    } 
    catch (const boost::system::system_error& e) {
        last_error_ = e.what();
    }
}

bool SerialPort::is_open() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return serial_port_.is_open();
}

bool SerialPort::send(const std::string& data) {
  //  std::cout<< "Sending data: " << data << std::endl;
    return send(std::vector<uint8_t>(data.begin(), data.end()));
}

bool SerialPort::send(const std::vector<uint8_t>& data) {
    if (data.empty()) {
        last_error_ = "发送数据为空";
        return false;
    }

    std::lock_guard<std::mutex> lock(mutex_);
    
    if (!serial_port_.is_open()) {
        last_error_ = "串口未打开";
        return false;
    }

    try {
        size_t bytes_sent = boost::asio::write(serial_port_, boost::asio::buffer(data));
        if (bytes_sent != data.size()) {
            last_error_ = "发送数据不完整";
            return false;
        }
        return true;
    } 
    catch (const boost::system::system_error& e) {
        last_error_ = e.what();
        return false;
    }
}

void SerialPort::set_receive_callback(ReceiveCallback callback) {
    std::lock_guard<std::mutex> lock(mutex_);
    receive_callback_ = callback;
}

std::string SerialPort::get_last_error() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return last_error_;
}

void SerialPort::receive_thread() {
    while (is_running_ && serial_port_.is_open()) {
        //std::cout<< "Starting async receive" << std::endl;
        try {
            // 异步读取数据
            serial_port_.async_read_some(
                boost::asio::buffer(receive_buffer_),
                boost::bind(
                    &SerialPort::async_receive_handler,
                    this,
                    boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred
                )
                
            );
            //std::cout<< "Starting async receive" << std::endl;
            // 运行IO服务
            io_service_.run();
            io_service_.reset();
            std::this_thread::sleep_for(std::chrono::milliseconds(2)); // 避免CPU占用过高
        } 
        catch (const boost::system::system_error& e) {
            std::lock_guard<std::mutex> lock(mutex_);
            last_error_ = e.what();
            
            // 如果不是主动关闭，等待一会儿再重试
            if (is_running_) {
                std::this_thread::sleep_for(std::chrono::milliseconds(10));
               // std::cout<< "Starting async delau" << std::endl;
            }
        }
    }
}

void SerialPort::async_receive_handler(const boost::system::error_code& error, std::size_t bytes_transferred) {
    if (error) {
        // 如果是操作已取消（通常是关闭串口时），不处理错误
        if (error != boost::asio::error::operation_aborted) {
            std::lock_guard<std::mutex> lock(mutex_);
            last_error_ = error.message();
        }
        return;
    }

    // 如果有数据且设置了回调函数，则触发回调
    if (bytes_transferred > 0 && receive_callback_) {
        std::vector<uint8_t> data(receive_buffer_.begin(), receive_buffer_.begin() + bytes_transferred);
        receive_callback_(data);
    }
}